SQLiteには、標準SQLでは実現できない高速な全文検索エンジン「FTS5」が搭載されています。 大量テキストの検索、ログ検索、メモアプリ、ナレッジ管理など、 業務アプリでも活躍する強力な機能です。
この記事でわかること
・FTS5とは何か(通常インデックスとの違い)
・仮想テーブルの作り方
・MATCH検索の使い方
・トークナイザー(形態素解析)
・ハイライト・スニペット
・WPF/MVVM × C# 実装例
・業務アプリ向けベストプラクティス
・FTS5とは何か(通常インデックスとの違い)
・仮想テーブルの作り方
・MATCH検索の使い方
・トークナイザー(形態素解析)
・ハイライト・スニペット
・WPF/MVVM × C# 実装例
・業務アプリ向けベストプラクティス
1. FTS5とは?(全文検索エンジン)
FTS5は、SQLiteに組み込まれた全文検索専用の仮想テーブルです。 通常のインデックスでは難しい「部分一致・単語検索・高速全文検索」を実現します。
■ 通常インデックスとの違い
| 項目 | 通常インデックス | FTS5 |
|---|---|---|
| 部分一致 | 遅い | 高速 |
| 全文検索 | 不可 | 可能 |
| 大量テキスト | 苦手 | 得意 |
| ハイライト | 不可 | 可能 |
ログ検索・メモ検索・ナレッジ検索などに最適です。
2. FTS5テーブルの作成
■ 基本構文
CREATE VIRTUAL TABLE Notes USING fts5(
Title,
Body,
tokenize = 'unicode61'
);
通常のCREATE TABLEではなく、 CREATE VIRTUAL TABLE を使う点がポイント。
■ トークナイザー(分かち書き)
- unicode61(標準)
- porter(英語ステミング)
- 自作トークナイザー(拡張)
日本語は形態素解析が必要な場合もありますが、 unicode61でも「部分一致検索」は十分実用的です。
3. データのINSERT
INSERT INTO Notes (Title, Body)
VALUES ('会議メモ', '次回の会議は4月10日 10:00 からです。');
通常のテーブルと同じようにINSERTできます。
4. MATCH検索(全文検索の基本)
■ 単語検索
SELECT rowid, Title FROM Notes
WHERE Notes MATCH '会議';
■ AND検索
WHERE Notes MATCH '会議 AND 4月'
■ OR検索
WHERE Notes MATCH '会議 OR メモ'
■ フレーズ検索
WHERE Notes MATCH '"次回の会議"'
通常のLIKE検索より圧倒的に高速です。
5. ハイライト・スニペット(検索結果の強調)
FTS5は検索結果のハイライト表示が可能です。
■ snippet()
SELECT snippet(Notes, 1, '', '', '...', 10)
FROM Notes
WHERE Notes MATCH '会議';
検索キーワードを 太字 にして抜粋を返します。
■ highlight()
SELECT highlight(Notes, 0, '[', ']')
FROM Notes
WHERE Notes MATCH '会議';
Title列の該当部分を [ ] で囲む。
6. C#(Dapper)で全文検索する
var sql = @"
SELECT rowid, Title, snippet(Notes, 1, '', '', '...', 10) AS Snippet
FROM Notes
WHERE Notes MATCH @query
ORDER BY rank;
";
var result = await con.QueryAsync<NoteSearchResult>(sql, new { query = "会議" });
ORDER BY rank で関連度順に並びます。
7. WPF/MVVMで全文検索UIを作る
■ ViewModel例
public class SearchViewModel : INotifyPropertyChanged
{
private readonly INoteSearchService _service;
public ObservableCollection<NoteSearchResult> Results { get; } = new();
public string Query { get; set; } = "";
public ICommand SearchCommand { get; }
public SearchViewModel(INoteSearchService service)
{
_service = service;
SearchCommand = new AsyncRelayCommand(SearchAsync);
}
private async Task SearchAsync()
{
var list = await _service.SearchAsync(Query);
Results.Clear();
foreach (var item in list)
Results.Add(item);
}
}
MVVMとFTS5は非常に相性が良いです。
8. FTS5の注意点(落とし穴)
① UPDATEが遅い(再インデックスが必要)
大量更新が多いテーブルには不向き。
② JOINができない(仮想テーブルの制約)
検索用テーブルを別に作るのが正解。
③ 日本語の精度はトークナイザー次第
必要なら形態素解析(Kuromojiなど)を導入。
9. 業務アプリ向けベストプラクティス
- 検索専用のFTS5テーブルを作る(正規化しすぎない)
- INSERT/UPDATEはバッチ処理でまとめる
- 検索は MATCH + snippet() で高速&見やすく
- WPFでは非同期検索でUIフリーズを防ぐ
- 大量データは rank で並び替える
- 日本語は unicode61 で部分一致検索が実用的
まとめ:FTS5は“SQLiteの隠れた最強機能”
- LIKE検索より圧倒的に高速
- 全文検索・ハイライト・スニペットが簡単
- 業務アプリの検索UXが劇的に向上
- WPF/MVVMとの相性も抜群
「SQLiteで全文検索したい」 そんなニーズに最も強力に応えるのがFTS5です。 この記事をベースに、あなたのアプリに高速検索を組み込んでみてください。